﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;

namespace SharpBroadcast
{
    public class ServerSetting
    {
        public int InputPort { get; set; }

        public List<string> InputWhitelist { get; set; }

        public int OutputPort { get; set; }

        public int OutputBufferSize { get; set; }

        public int OutputQueueSize { get; set; }

        public int CacheQueueSize { get; set; }

        public ServerSetting()
        {
            InputPort = 9100;
            InputWhitelist = new List<string>() { "127.0.0.1" };
            OutputPort = 9200;
            OutputBufferSize = 256;
            OutputQueueSize = 256;
            CacheQueueSize = 0;
        }

        public static ServerSetting Reload(IServerLogger logger, string prefix = "")
        {
            ServerSetting setting = new ServerSetting();

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            if (prefix.Length > 0) logger.Info("Reloading config (" + prefix + ") from file " + config.FilePath);
            else logger.Info("Reloading config from file " + config.FilePath);

            ConfigurationManager.RefreshSection("appSettings");

            try
            {
                string portInput = setting.InputPort.ToString();
                string listInput = String.Join(",", setting.InputWhitelist.ToArray());

                string portOutput = setting.OutputPort.ToString();

                string sizeBuffer = setting.OutputBufferSize.ToString();
                string sizeQueue = setting.OutputQueueSize.ToString();

                string sizeCache = setting.CacheQueueSize.ToString();

                var appSettings = ConfigurationManager.AppSettings;
                var allKeys = appSettings.AllKeys;

                if (allKeys.Contains(prefix + "InputPort")) portInput = appSettings[prefix + "InputPort"];
                if (allKeys.Contains(prefix + "InputWhitelist")) listInput = appSettings[prefix + "InputWhitelist"];
                if (allKeys.Contains(prefix + "OutputPort")) portOutput = appSettings[prefix + "OutputPort"];
                if (allKeys.Contains(prefix + "OutputBufferSize")) sizeBuffer = appSettings[prefix + "OutputBufferSize"];
                if (allKeys.Contains(prefix + "OutputQueueSize")) sizeQueue = appSettings[prefix + "OutputQueueSize"];
                if (allKeys.Contains(prefix + "CacheQueueSize")) sizeCache = appSettings[prefix + "CacheQueueSize"];

                if (listInput != null && listInput.Length > 0)
                {
                    var items = listInput.Split(',').ToList();
                    if (items.Count > 0)
                    {
                        setting.InputWhitelist.Clear();
                        foreach (var item in items)
                        {
                            setting.InputWhitelist.Add(item.Trim());
                        }
                    }
                }

                setting.InputPort = Int32.Parse(portInput);
                setting.OutputPort = Int32.Parse(portOutput);

                setting.OutputBufferSize = Int32.Parse(sizeBuffer);
                setting.OutputQueueSize = Int32.Parse(sizeQueue);

                setting.CacheQueueSize = Int32.Parse(sizeCache);

                logger.Info("Reloaded all config.");
            }
            catch (Exception ex)
            {
                logger.Error("Failed to load config from file. Error: " + ex);
            }

            return setting;
        }

        public static ServerSetting Reload(string prefix = "")
        {
            return Reload(new ConsoleLogger(), prefix);
        }
    }
}
